using System;
using System.IO;
using System.Linq;
using System.Data;
using System.Reflection;
using System.Collections;
using System.ComponentModel;
using System.Linq.Expressions;
using System.Collections.Generic;
using System.Runtime.Serialization;
using System.Runtime.Serialization.Formatters.Binary;

namespace UtilTools
{
    /// <summary>
    /// 实用拓展
    /// </summary>
    public static class Expand
    {
        #region 全局散列存储
        private static Hashtable hashtable;
        private static Hashtable EnumHash
        {
            get
            {
                if (null == hashtable) { hashtable = new Hashtable(); }
                return hashtable;
            }
        }
        #endregion

        #region 枚举描述
        /// <summary>
        /// 获取枚举字符串
        /// </summary>
        /// <typeparam name="TEnum"></typeparam>
        /// <param name="key"></param>
        /// <returns></returns>
        public static String GetString<TEnum>(this Int32 key) => ToIntDictionary<TEnum>(e => e.ToString())[key];

        /// <summary>
        /// 获取枚举描述
        /// </summary>
        /// <returns></returns>
        public static String GetDescription<TEnum>(this Int32 key) => ToIntDictionary<TEnum>(e => e.GetDescription())[key];

        /// <summary>
        /// 获取枚举描述
        /// </summary>
        /// <returns></returns>
        public static String GetDescription(this Enum value)
        {
            if (value == null) { throw new ArgumentNullException("枚举类型不存在"); }
            var keyvalue = GetDescription(value.GetType());
            return keyvalue[value.ToString()];
        }

        /// <summary>
        /// 根据枚举类型和枚举值获取枚举描述
        /// </summary>
        /// <param name="enumType">枚举类型</param>
        /// <returns></returns>
        private static Dictionary<String, String> GetDescription(Type enumType)
        {
            var typeName = enumType.FullName;
            if (!EnumHash.ContainsKey(typeName)) { EnumHash.Add(typeName, GetEnumDic(enumType)); }
            var enums = EnumHash[typeName];
            if (null == enums) { throw new NullReferenceException("枚举描述不存在"); }
            return (Dictionary<string, string>)enums;
        }

        /// <summary>
        /// 获取枚举所有特性描述
        /// </summary>
        /// <returns></returns>
        private static Dictionary<String, String> GetEnumDic(Type enumType)
        {
            var enumdic = new Dictionary<string, string>();
            FieldInfo[] fieldinfos = enumType.GetFields();
            foreach (FieldInfo field in fieldinfos)
            {
                if (field.FieldType.IsEnum)
                {
                    var objs = field.GetCustomAttributes(typeof(DescriptionAttribute), false);
                    var attributeString = objs.Length > 0 ? ((DescriptionAttribute)objs[0])?.Description ?? field.Name : field.Name;
                    enumdic.Add(field.Name, attributeString);
                }
            }
            return enumdic;
        }

        /// <summary>
        /// 获取枚举字典
        /// </summary>
        /// <typeparam name="TEnum">枚举</typeparam>
        /// <returns></returns>
        public static Dictionary<String, String> ToStringDictionary<TEnum>()
        {
            Type type = typeof(TEnum);
            if (!type.IsEnum) { throw new ArgumentException("泛型参数必须为枚举类型"); }
            return GetDescription(type);
        }

        /// <summary>
        /// 获取枚举字典
        /// </summary>
        /// <typeparam name="TEnum">枚举</typeparam>
        /// <param name="GetString">e=>e.GetDescription() || e.ToString()</param>
        /// <returns></returns>
        public static Dictionary<Int32, String> ToIntDictionary<TEnum>(Func<Enum, String> GetString)
        {
            Type type = typeof(TEnum);
            if (!type.IsEnum) { throw new ArgumentException("泛型参数必须为枚举类型"); }
            var keyvalues = new Dictionary<int, string>();
            foreach (Enum item in Enum.GetValues(type))
            {
                keyvalues.Add(Convert.ToInt32(item), GetString(item));
            }
            return keyvalues;
        }
        #endregion

        #region 类型转换
        /// <summary>
        /// 
        /// </summary>
        /// <param name="value"></param>
        /// <param name="error"></param>
        /// <returns></returns>
        public static Byte ObjToByte(this Object value, Byte error = 0)
        {
            Byte reval = 0;
            if (value != null && value != DBNull.Value && Byte.TryParse(value.ToString(), out reval))
            {
                return reval;
            }
            return error;
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="value"></param>
        /// <param name="error"></param>
        /// <returns></returns>
        public static Boolean ObjToBool(this Object value, Boolean error = false)
        {
            Boolean reval = false;
            if (value != null && value != DBNull.Value && bool.TryParse(value.ToString(), out reval))
            {
                return reval;
            }
            return error;
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="value"></param>
        /// <param name="error"></param>
        /// <returns></returns>
        public static Int16 ObjToInt16(this Object value, Int16 error = 0)
        {
            Int16 reval = 0;
            if (value != null && value != DBNull.Value && Int16.TryParse(value.ToString(), out reval))
            {
                return reval;
            }
            return error;
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="value"></param>
        /// <param name="error"></param>
        /// <returns></returns>
        public static Nullable<Int16> ObjToInt16(this Object value, Nullable<Int16> error = null)
        {
            Int16 reval = 0;
            if (value != null && value != DBNull.Value && Int16.TryParse(value.ToString(), out reval))
            {
                return reval;
            }
            return error;
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="value"></param>
        /// <param name="error"></param>
        /// <returns></returns>
        public static Int32 ObjToInt32(this Object value, Int32 error = 0)
        {
            Int32 reval = 0;
            if (value != null && value != DBNull.Value && Int32.TryParse(value.ToString(), out reval))
            {
                return reval;
            }
            return reval;
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="value"></param>
        /// <param name="error"></param>
        /// <returns></returns>
        public static Nullable<Int32> ObjToInt32(this Object value, Nullable<Int32> error = null)
        {
            Int32 reval = 0;
            if (value != null && value != DBNull.Value && Int32.TryParse(value.ToString(), out reval))
            {
                return reval;
            }
            return error;
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="value"></param>
        /// <param name="error"></param>
        /// <returns></returns>
        public static Int64 ObjToInt64(this Object value, Int64 error = 0)
        {
            Int64 reval = 0;
            if (value != null && value != DBNull.Value && Int64.TryParse(value.ToString(), out reval))
            {
                return reval;
            }
            return error;
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="value"></param>
        /// <param name="error"></param>
        /// <returns></returns>
        public static Nullable<Int64> ObjToInt64(this Object value, Nullable<Int64> error = null)
        {
            Int64 reval = 0;
            if (value != null && value != DBNull.Value && Int64.TryParse(value.ToString(), out reval))
            {
                return reval;
            }
            return error;
        }
        /// <summary>
        /// 转Decimal
        /// </summary>
        /// <param name="value"></param>
        /// <param name="error"></param>
        /// <returns></returns>
        public static Decimal ObjToDecimal(this Object value, Decimal error = 0)
        {
            Decimal reval = 0;
            if (value != null && value != DBNull.Value && Decimal.TryParse(value.ToString(), out reval))
            {
                return reval;
            }
            return error;
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="value"></param>
        /// <param name="error"></param>
        /// <returns></returns>
        public static Nullable<Decimal> ObjToDecimal(this Object value, Nullable<Decimal> error = 0)
        {
            Decimal reval = 0;
            if (value != null && value != DBNull.Value && decimal.TryParse(value.ToString(), out reval))
            {
                return reval;
            }
            return error;
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="value"></param>
        /// <returns></returns>
        public static DateTime ObjToDate(this Object value)
        {
            DateTime reval = DateTime.MinValue;
            if (value != null && value != DBNull.Value && DateTime.TryParse(value.ToString(), out reval))
            {
                return reval;
            }
            return DateTime.Parse("1970-01-01");
        }
        /// <summary>
        /// 转时间戳 (10位)
        /// </summary>
        /// <param name="date"></param>
        /// <returns></returns>
        public static Int32 ToStamp(this DateTime date)
        {
            DateTime StartTime = new DateTime(1970, 1, 1, 8, 0, 0);
            if (date < StartTime) { return 0; }
            return Convert.ToInt32(date.Subtract(StartTime).TotalSeconds);
        }
        /// <summary>
        /// 转时间戳 (13位)
        /// </summary>
        /// <param name="date"></param>
        /// <returns></returns>
        public static Int64 ToLongStamp(this DateTime date)
        {
            DateTime StartTime = new DateTime(1970, 1, 1, 8, 0, 0);
            return Convert.ToInt64(date.Subtract(StartTime).TotalMilliseconds);
        }
        /// <summary>
        /// 转DATETIME (10位)
        /// </summary>
        /// <param name="timestamp"></param>
        /// <returns></returns>
        public static DateTime ToDateTime(this Int32 timestamp)
        {
            DateTime StartTime = TimeZone.CurrentTimeZone.ToLocalTime(new DateTime(1970, 1, 1));
            return StartTime.AddSeconds(timestamp);
        }
        /// <summary>
        /// 转DATETIME (10位)
        /// </summary>
        /// <param name="timestamp"></param>
        /// <param name="isNull"></param>
        /// <returns></returns>
        public static Nullable<DateTime> ToDateTime(this Int32 timestamp, Boolean isNull = true)
        {
            if (timestamp <= 0 && isNull) { return null; }
            DateTime StartTime = TimeZone.CurrentTimeZone.ToLocalTime(new DateTime(1970, 1, 1));
            return StartTime.AddSeconds(timestamp);
        }
        /// <summary>
        /// 转DATETIME (13位)
        /// </summary>
        /// <param name="timestamp"></param>
        /// <returns></returns>
        public static DateTime ToDateTime(this Int64 timestamp)
        {
            DateTime StartTime = TimeZone.CurrentTimeZone.ToLocalTime(new DateTime(1970, 1, 1));
            return StartTime.AddMilliseconds(timestamp);
        }
        /// <summary>
        /// 转DATETIME (13位)
        /// </summary>
        /// <param name="timestamp"></param>
        /// <param name="isNull"></param>
        /// <returns></returns>
        public static Nullable<DateTime> ToDateTime(this Int64 timestamp, Boolean isNull = true)
        {
            if (timestamp <= 0 && isNull) { return null; }
            DateTime StartTime = TimeZone.CurrentTimeZone.ToLocalTime(new DateTime(1970, 1, 1));
            return StartTime.AddMilliseconds(timestamp);
        }
        /// <summary>
        /// 人民币大写转阿拉伯数字
        /// 数据边界值:玖佰玖拾玖亿玖仟玖佰玖拾玖万玖仟玖佰玖拾玖元玖角玖分
        /// </summary>
        /// <param name="chinese">需要转换的字符串</param>
        /// <returns>阿拉伯数字</returns>
        public static Double ToNumber(this String chinese)
        {
            if (String.IsNullOrWhiteSpace(chinese)) { return 0; }
            var Rmb = chinese.Replace("零", "").Replace("整", "").ToCharArray();
            if (chinese.Contains("佰"))
            {
                var _TempStr = chinese.Replace("佰", "");
                if ((chinese.Length - _TempStr.Length) > 3) { throw new Exception("数据超过边界值"); }
            }
            if (chinese.Contains("仟"))
            {
                var _TempStr = chinese.Replace("仟", "");
                if ((chinese.Length - _TempStr.Length) > 2) { throw new Exception("数据超过边界值"); }
            }
            if (chinese.Contains("万"))
            {
                var _TempStr = chinese.Replace("万", "");
                if ((chinese.Length - _TempStr.Length) > 1) { throw new Exception("数据超过边界值"); }
            }
            if (chinese.Contains("亿"))
            {
                var _TempStr = chinese.Replace("亿", "");
                if ((chinese.Length - _TempStr.Length) > 1) { throw new Exception("数据超过边界值"); }
            }
            Double Arab = 0;
            Boolean Unit_Yi = false, Unit_Wan = false, Unit_Qian = false, Unit_Bai = false, Unit_Shi = false, Unit_Yuan = false, Unit_Jiao = false, Unit_Fen = false;
            for (Int32 i = (Rmb.Length - 1); i >= 0; i--)
            {
                Double _tempArab = 0;
                #region 激活单位
                switch (Rmb[i].ToString())
                {
                    case "分":
                        Unit_Fen = true;
                        continue;
                    case "角":
                        Unit_Fen = false; Unit_Jiao = true;
                        continue;
                    case "元":
                        Unit_Fen = false; Unit_Jiao = false; Unit_Yuan = true;
                        continue;
                    case "拾":
                        Unit_Fen = false; Unit_Jiao = false; Unit_Yuan = false; Unit_Shi = true;
                        continue;
                    case "佰":
                        Unit_Fen = false; Unit_Jiao = false; Unit_Yuan = false; Unit_Shi = false; Unit_Bai = true;
                        continue;
                    case "仟":
                        Unit_Fen = false; Unit_Jiao = false; Unit_Yuan = false; Unit_Shi = false; Unit_Bai = false; Unit_Qian = true;
                        continue;
                    case "万":
                        Unit_Fen = false; Unit_Jiao = false; Unit_Yuan = false; Unit_Shi = false; Unit_Bai = false; Unit_Qian = false; Unit_Wan = true;
                        continue;
                    case "亿":
                        Unit_Fen = false; Unit_Jiao = false; Unit_Yuan = false; Unit_Shi = false; Unit_Bai = false; Unit_Qian = false; Unit_Wan = false; Unit_Yi = true;
                        continue;
                }
                #endregion

                #region 临时金额计算
                Double number = 0;
                switch (Rmb[i].ToString())
                {
                    case "零": number = 0; break;
                    case "壹": number = 1; break;
                    case "贰": number = 2; break;
                    case "叁": number = 3; break;
                    case "肆": number = 4; break;
                    case "伍": number = 5; break;
                    case "陆": number = 6; break;
                    case "柒": number = 7; break;
                    case "捌": number = 8; break;
                    case "玖": number = 9; break;
                }
                if (Unit_Fen) { _tempArab = number * 0.01; }
                else if (Unit_Jiao) { _tempArab = number * 0.1; }
                else if (Unit_Yuan) { _tempArab = number * 1; }
                else if (Unit_Shi) { _tempArab = number * 10; }
                else if (Unit_Bai) { _tempArab = number * 100; }
                else if (Unit_Qian) { _tempArab = number * 1000; }
                else { _tempArab = number; }

                if (Unit_Yi) { _tempArab = _tempArab * 100000000; }
                if (Unit_Wan) { _tempArab = _tempArab * 10000; }
                #endregion
                Arab += _tempArab;
            }
            return Arab;
        }
        /// <summary> 
        /// 转换人民币大小金额 
        /// </summary> 
        /// <param name="num">金额</param> 
        /// <returns>返回大写形式</returns> 
        public static String ToChinese(this Decimal num)
        {
            String str1 = "零壹贰叁肆伍陆柒捌玖";
            String str2 = "万仟佰拾亿仟佰拾万仟佰拾元角分";
            String str3 = "";
            String str4 = "";
            String str5 = "";
            Int32 i;
            Int32 j;
            String ch1 = "";
            String ch2 = "";
            Int32 nzero = 0;
            Int32 temp;
            num = Math.Round(Math.Abs(num), 2);
            str4 = ((long)(num * 100)).ToString();
            j = str4.Length;
            if (j > 15) { return "溢出"; }
            str2 = str2.Substring(15 - j);
            for (i = 0; i < j; i++)
            {
                str3 = str4.Substring(i, 1);
                temp = Convert.ToInt32(str3);
                if (i != (j - 3) && i != (j - 7) && i != (j - 11) && i != (j - 15))
                {
                    if (str3 == "0")
                    {
                        ch1 = "";
                        ch2 = "";
                        nzero = nzero + 1;
                    }
                    else
                    {
                        if (str3 != "0" && nzero != 0)
                        {
                            ch1 = "零" + str1.Substring(temp * 1, 1);
                            ch2 = str2.Substring(i, 1);
                            nzero = 0;
                        }
                        else
                        {
                            ch1 = str1.Substring(temp * 1, 1);
                            ch2 = str2.Substring(i, 1);
                            nzero = 0;
                        }
                    }
                }
                else
                {
                    if (str3 != "0" && nzero != 0)
                    {
                        ch1 = "零" + str1.Substring(temp * 1, 1);
                        ch2 = str2.Substring(i, 1);
                        nzero = 0;
                    }
                    else
                    {
                        if (str3 != "0" && nzero == 0)
                        {
                            ch1 = str1.Substring(temp * 1, 1);
                            ch2 = str2.Substring(i, 1);
                            nzero = 0;
                        }
                        else
                        {
                            if (str3 == "0" && nzero >= 3)
                            {
                                ch1 = "";
                                ch2 = "";
                                nzero = nzero + 1;
                            }
                            else
                            {
                                if (j >= 11)
                                {
                                    ch1 = "";
                                    nzero = nzero + 1;
                                }
                                else
                                {
                                    ch1 = "";
                                    ch2 = str2.Substring(i, 1);
                                    nzero = nzero + 1;
                                }
                            }
                        }
                    }
                }
                if (i == (j - 11) || i == (j - 3))
                {
                    ch2 = str2.Substring(i, 1);
                }
                str5 = str5 + ch1 + ch2;
                if (i == j - 1 && str3 == "0")
                {
                    str5 = str5 + '整';
                }
            }
            if (num == 0) { str5 = "零元整"; }
            return str5;
        }
        /// <summary>
        /// 方法重载
        /// </summary>
        /// <param name="num"></param>
        /// <returns></returns>
        public static String ToChinese(this Int32 num) => ToChinese((Decimal)num);
        /// <summary>
        /// 键值对转模型
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="dic"></param>
        /// <returns></returns>
        public static T DicToModel<T>(this Dictionary<String, Object> dic)
        {
            Type type = typeof(T);
            T result = Activator.CreateInstance<T>();
            List<PropertyInfo> list = type.GetProperties().ToList();
            foreach (var kv in dic)
            {
                PropertyInfo info = typeof(T).GetProperties()
                    .Where(item => item.Name.Equals(kv.Key, StringComparison.OrdinalIgnoreCase))
                    .FirstOrDefault();
                if (info != null) { result.SetValue(info, kv.Value); }
            }
            return result;
        }
        /// <summary>
        /// 键值对转模型
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="dic"></param>
        /// <param name="model"></param>
        /// <returns></returns>
        public static T DicToModel<T>(this Dictionary<String, Object> dic, T model)
        {
            Type type = typeof(T);
            List<PropertyInfo> list = type.GetProperties().ToList();
            foreach (var kv in dic)
            {
                PropertyInfo info = typeof(T).GetProperties()
                    .Where(item => item.Name.Equals(kv.Key, StringComparison.OrdinalIgnoreCase))
                    .FirstOrDefault();
                if (info != null) { model.SetValue(info, kv.Value); }
            }
            return model;
        }
        /// <summary>
        /// 将DataTable转换成实体对象
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="dt"></param>
        /// <returns></returns>
        public static List<T> DataTableToModel<T>(this DataTable dt)
        {
            List<T> data = new List<T>();
            foreach (DataRow row in dt.Rows) { data.Add(row.DataRowToModel<T>()); }
            return data;
        }
        /// <summary>
        /// 将DataRow转换成实体对象
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="dr"></param>
        /// <returns></returns>
        public static T DataRowToModel<T>(this DataRow dr)
        {
            try
            {
                Type temp = typeof(T);
                T obj = Activator.CreateInstance<T>();
                foreach (DataColumn column in dr.Table.Columns)
                {
                    foreach (PropertyInfo pro in temp.GetProperties())
                    {
                        if (pro.Name.ToLower() == column.ColumnName.ToLower())
                        {
                            if (dr[column.ColumnName] == DBNull.Value)
                            {
                                pro.SetValue(obj, null, null);
                            }
                            else { obj.SetValue(pro, dr[column.ColumnName]); }
                            break;
                        }
                    }
                }
                return obj;
            }
            catch (Exception ex)
            {
                throw new Exception(ex.Message);
            }
        }
        /// <summary>
        /// 设置值
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="info"></param>
        /// <param name="value"></param>
        /// <param name="model"></param>
        public static void SetValue<T>(this T model, PropertyInfo info, Object value)
        {
            if (info.PropertyType == typeof(Decimal))
            {
                info.SetValue(model, value.ObjToDecimal(0), null);
            }
            else if (info.PropertyType == typeof(Nullable<Decimal>))
            {
                info.SetValue(model, value.ObjToDecimal(null), null);
            }
            else if (info.PropertyType == typeof(Int16))
            {
                info.SetValue(model, value.ObjToInt16(0), null);
            }
            else if (info.PropertyType == typeof(Nullable<Int16>))
            {
                info.SetValue(model, value.ObjToInt16(null), null);
            }
            else if (info.PropertyType == typeof(Int32))
            {
                info.SetValue(model, value.ObjToInt32(0), null);
            }
            else if (info.PropertyType == typeof(Nullable<Int32>))
            {
                info.SetValue(model, value.ObjToInt32(null), null);
            }
            else if (info.PropertyType == typeof(Int64))
            {
                info.SetValue(model, value.ObjToInt64(0), null);
            }
            else if (info.PropertyType == typeof(Nullable<Int64>))
            {
                info.SetValue(model, value.ObjToInt64(null), null);
            }
            else if (info.PropertyType == typeof(Nullable<Byte>) || info.PropertyType == typeof(Byte))
            {
                info.SetValue(model, value.ObjToByte(), null);
            }
            else if (info.PropertyType == typeof(Nullable<Boolean>) || info.PropertyType == typeof(Boolean))
            {
                info.SetValue(model, value.ObjToBool(), null);
            }
            else if (info.PropertyType == typeof(SByte))
            {
                info.SetValue(model, Convert.ToSByte(value), null);
            }
            else { info.SetValue(model, value.ToString(), null); }
        }
        #endregion

        #region 深度拷贝
        /// <summary>
        /// 深度拷贝
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="model"></param>
        /// <returns></returns>
        public static T Clone<T>(this T model) where T : class
        {
            T val = Activator.CreateInstance<T>();
            PropertyInfo[] properties = model.GetType().GetProperties();
            foreach (PropertyInfo propertyInfo in properties)
            {
                if (propertyInfo.CanWrite)
                {
                    if (propertyInfo.PropertyType.IsGenericType && propertyInfo.PropertyType.GetGenericTypeDefinition().Equals(typeof(Nullable<>)))
                    {
                        NullableConverter nullableConverter = new NullableConverter(propertyInfo.PropertyType);
                        propertyInfo.SetValue(val, Convert.ChangeType(propertyInfo.GetValue(model, null), nullableConverter.UnderlyingType), null);
                    }
                    else { propertyInfo.SetValue(val, Convert.ChangeType(propertyInfo.GetValue(model, null), propertyInfo.PropertyType), null); }
                }
            }
            return val;
        }
        /// <summary>
        /// 深度拷贝
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="model"></param>
        /// <returns></returns>
        public static List<T> Clone<T>(this List<T> model)
        {
            using (Stream objectStream = new MemoryStream())
            {
                IFormatter formatter = new BinaryFormatter();
                formatter.Serialize(objectStream, model);
                objectStream.Seek(0, SeekOrigin.Begin);
                return (List<T>)formatter.Deserialize(objectStream);
            }
        }
        /// <summary>
        /// 深度拷贝
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="models"></param>
        /// <returns></returns>
        public static List<T> Clone<T>(this IEnumerable<T> models)
        {
            using (Stream objectStream = new MemoryStream())
            {
                IFormatter formatter = new BinaryFormatter();
                formatter.Serialize(objectStream, models.ToList());
                objectStream.Seek(0, SeekOrigin.Begin);
                return (List<T>)formatter.Deserialize(objectStream);
            }
        }
        #endregion

        #region Json转换
        /// <summary>
        /// 转换对象为Json
        /// </summary>
        /// <param name="Obj">需要转换的对象</param>
        /// <param name="WithFormat">是否包含字符格式</param>
        /// <param name="WithNull">是否包含Null值</param>
        /// <param name="UseCamelCase">驼峰序列化[默认:false]</param>
        /// <returns></returns>
        public static String ToJson(this Object Obj, Boolean WithFormat = true, Boolean WithNull = true, Boolean UseCamelCase = false)
        {
            try
            {
                if (null == Obj) { return String.Empty; }
                Newtonsoft.Json.Formatting JFormat = Newtonsoft.Json.Formatting.None;
                Newtonsoft.Json.NullValueHandling JNull = Newtonsoft.Json.NullValueHandling.Ignore;
                Newtonsoft.Json.Serialization.CamelCasePropertyNamesContractResolver CamelCase = new Newtonsoft.Json.Serialization.CamelCasePropertyNamesContractResolver();
                if (WithFormat) { JFormat = Newtonsoft.Json.Formatting.Indented; }
                if (WithNull) { JNull = Newtonsoft.Json.NullValueHandling.Include; }
                Newtonsoft.Json.JsonSerializerSettings JSet = new Newtonsoft.Json.JsonSerializerSettings { NullValueHandling = JNull, DateFormatString = "yyyy-MM-dd HH:mm:ss" };
                if (UseCamelCase) { JSet.ContractResolver = CamelCase; }
                return Newtonsoft.Json.JsonConvert.SerializeObject(Obj, JFormat, JSet);
            }
            catch (Exception ex) { throw ex; }

        }

        /// <summary>
        /// Json字符串转换为对象
        /// </summary>
        /// <typeparam name="T">对象类型</typeparam>
        /// <param name="JsonStr">Json字符串</param>
        /// <returns></returns>
        public static T JsonTo<T>(this String JsonStr) where T : class, new()
        {
            try
            {
                if (String.IsNullOrWhiteSpace(JsonStr)) { throw new ArgumentException("The parameter is empty"); }
                return Newtonsoft.Json.JsonConvert.DeserializeObject<T>(JsonStr);
            }
            catch (Exception ex) { throw ex; }
        }
        #endregion
    }
}
